package com.caochenlei.queue;

public class CircularQueue<E> {
    private int front;      //指向队头元素，默认为0
    private int rear;       //指向队尾元素，默认为0
    private E[] elements;   //存放队列元素，默认为null
    private int maxSize;    //队列最大容量，默认为0

    public CircularQueue(int capacity) {
        maxSize = capacity + 1;                     //有一个没用的元素，所以这里加一
        elements = (E[]) new Object[capacity + 1];  //有一个没用的元素，所以这里加一
    }

    //判断队列是否为空
    public boolean isEmpty() {
        return front == rear;
    }

    //判断队列是否已满
    public boolean isFull() {
        return ((rear + 1) % maxSize) == front;
    }

    //获取队列元素个数
    public int size() {
        return (rear - front + maxSize) % maxSize;
    }

    //入队列
    public void enqueue(E element) {
        //判断队列是否已满
        if (isFull()) {
            System.out.println("队列已满，插入失败：" + element);
            return;
        }
        //入队列
        elements[rear] = element;
        //向后移
        rear = (rear + 1) % maxSize;
    }

    //出队列
    public E dequeue() {
        //判断队列是否为空
        if (isEmpty()) {
            System.out.println("队列已空，获取失败");
            return null;
        }
        //出队列
        E element = elements[front];
        //向后移
        front = (front + 1) % maxSize;
        return element;
    }

    @Override
    public String toString() {
        //获取队列有效元素
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = front; i < front + size(); i++) {
            sb.append(" " + elements[i % maxSize] + " ");
        }
        sb.append("]");
        //返回队列详细信息
        return "SequentialQueue{" +
                "front=" + front +
                ", rear=" + rear +
                ", elements=" + sb.toString() +
                ", eleSize=" + size() +
                ", maxSize=" + (maxSize - 1) + //有一个没用的元素，所以这里减一
                ", isEmpty=" + isEmpty() +
                ", isFull=" + isFull() +
                '}';
    }
}
